/*
 * sdl renderer font
 * 
 * #include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
SDL_Texture *text ( const char *Fonts, int FontSize, SDL_Renderer *Render, const char *FontsPath, int r = 0, int g = 0, int b = 0, int a = 0 )
{
	TTF_Init();
	TTF_Font *font = NULL;
	font = TTF_OpenFont ( FontsPath, FontSize );
	SDL_Color color;
	color.r = r;
	color.g = g;
	color.b = b;
	color.a = a;
	SDL_Surface *temp = NULL;
	SDL_Texture *fonts = NULL;
	temp = TTF_RenderUTF8_Blended ( font, Fonts, color );
	fonts = SDL_CreateTextureFromSurface ( Render, temp );
	SDL_FreeSurface ( temp );
	TTF_CloseFont ( font );
	TTF_Quit();
	* return  fonts;
}
int main ( int args, char *argv[] )
{
	SDL_Window *win = NULL;
	SDL_Surface *face = NULL;
	SDL_Renderer *ren = NULL;
	SDL_Texture *tex = NULL;
	SDL_Init ( SDL_INIT_VIDEO );
	win = SDL_CreateWindow ( "", 0, 0, 200, 240, SDL_WINDOW_SHOWN );
	ren = SDL_CreateRenderer ( win, -1, SDL_RENDERER_ACCELERATED );
	SDL_Rect box;
	tex = text ( "我就看看", 28, ren, "/system/fonts/DroidSansFallback.ttf", 200 );
	box.x = 0;
	box.y = 0;
	int w = 0, h = 0;
	SDL_QueryTexture ( tex, NULL, NULL, &w, &h );
	box.w = w;
	box.h = h;
	SDL_RenderClear ( ren );
	SDL_RenderCopy ( ren, tex, NULL, &box );
	SDL_RenderPresent ( ren );
	SDL_Delay ( 5000 );
	SDL_DestroyWindow ( win );
	SDL_DestroyTexture ( tex );
	SDL_DestroyRenderer ( ren );
	TTF_Quit();
	SDL_Quit();
	return 0;
}
* SDL_CreateTextureFromSurface ( Render, temp );
 */
#include  <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include "Color.h"
#include <string>
using namespace std;

namespace Eyas3D
{
	namespace Core
	{
	//也是建立在sdl_surface上
	//绑定在renderer上
	//int SDL_BlitSurface(SDL_Surface*    src,    const SDL_Rect* srcrect,                  SDL_Surface*    dst,                    SDL_Rect*       dstrect)
	//先建立一个surface,然后blit到screen_surface上?
	//pTexture = SDL_CreateTextureFromSurface(pRenderer,pTmpSurface); 
	//直接对SDL_RenderDrawLine操作
		class Draw
		{
		private:
			//一个副本
			SDL_Renderer *m_renderer = NULL;
			SDL_Window *m_window = NULL;
			//SDL_Renderer* SDL_GetRenderer(SDL_Window* window)
			/*SDL_Window* SDL_CreateWindow(const char* title,
								 int         x,
								 int         y,
								 int         w,
								 int         h,
								 Uint32      flags)
			*/
		public:
			Draw( SDL_Window* window ){
				//依托在本窗口上渲染器的描绘
				m_window = window;
				m_renderer = SDL_GetRenderer( window );
				if( m_renderer == NULL )
					m_renderer = SDL_CreateRenderer( window, -1, 0 );
			}
			~Draw(){
				SDL_DestroyRenderer( m_renderer );
			}
			/* 初始化绘图系统 */
			bool initGraphics( );
			/* 关闭绘图系统 */
			void shutdownGraphics(){
				//SDL_DestroyWindow( window );
				SDL_QuitSubSystem(SDL_INIT_VIDEO);
			}
			/* 检测z值, 返回true则表示通过, 可以调用setPixel */
			bool checkZ( int x, int y, float z );
			Color getPixel( int x, int y )/////////////////////////SDL_Surface* SDL_GetWindowSurface(SDL_Window* window)
			{
				//SDL_Surface* surface = SDL_GetWindowSurface( m_window );
				//return SDL_RenderReadPixels(
				//This is a very slow operation, and should not be used frequently.why
				/*int SDL_RenderReadPixels(SDL_Renderer*   renderer,
							 const SDL_Rect* rect,
							 Uint32          format,
							 void*           pixels,
							 int             pitch)*/
				SDL_Rect rect;
				rect.x = y;	rect.y=y;	rect.w=1;	rect.h=1;	Color pixel;
				SDL_RenderReadPixels( m_renderer, &rect, 0, &pixel, 1 );
				return pixel;
			}
			//画点
			void drawPoint( int x, int y, Color &c ){
				SDL_SetRenderDrawColor( m_renderer, c.r, c.g, c.b, c.a );
				SDL_RenderDrawPoint( m_renderer, x, y );
			}
			void drawPoint( int x, int y, unsigned char r, unsigned char g, unsigned char b, unsigned char a ){
				SDL_SetRenderDrawColor( m_renderer, r, g, b, a );
				SDL_RenderDrawPoint( m_renderer, x, y );
			}
			//画线
			void drawLine( int x0, int y0, int x1, int y1, const Color &c ){
				/*int SDL_RenderDrawLine(SDL_Renderer* renderer,
						   int           x1,
						   int           y1,
						   int           x2,
						   int           y2)*///SDL_ALPHA_OPAQUE 255
				SDL_SetRenderDrawColor( m_renderer, c.r, c.g, c.b, c.a );
				SDL_RenderDrawLine( m_renderer, x0, y0, x1, x1 );
			}
			void drawLine( int x0, int y0, int x1, int y1, unsigned char r, unsigned char g, unsigned char b, unsigned char a ){
				SDL_SetRenderDrawColor( m_renderer, r, g, b, a );
				SDL_RenderDrawLine( m_renderer, x0, y0, x1, x1 );
			}
			//写字
			static SDL_Texture *stringTexture ( SDL_Renderer *Render, const char *fontpath, int FontSize, const char *str, int r = 0, int g = 0, int b = 0, int a = 0 )
			{
				TTF_Init();
				TTF_Font *font = NULL;
				font = TTF_OpenFont ( fontpath, FontSize );
				if( font==NULL ){
					SDL_Log( "ttf file open error");
					return NULL;
				}
				SDL_Color color;
				color.r = r;
				color.g = g;
				color.b = b;
				color.a = a;
				SDL_Surface *temp = NULL;
				SDL_Texture *fonts = NULL;
				temp = TTF_RenderUTF8_Blended ( font, str, color );
				fonts = SDL_CreateTextureFromSurface ( Render, temp );
				SDL_FreeSurface ( temp );
				TTF_CloseFont ( font );
				TTF_Quit();
				return fonts;
			}
			void drawString( const char* fontpath, int fontsize, int x, int y, const char* str, const Color &c = Color( 255, 255, 255 ) ){
				SDL_Rect box;
				SDL_Texture* tex = stringTexture ( m_renderer, fontpath, fontsize, str, c.r, c.g, c.b );
				box.x = x;
				box.y = y;
				int w = 0, h = 0;
				//获得texture的长宽
				SDL_QueryTexture ( tex, NULL, NULL, &w, &h );
				box.w = w;
				box.h = h;
				//SDL_RenderClear ( m_renderer );
				SDL_RenderCopy ( m_renderer, tex, NULL, &box );
				//SDL_RenderPresent ( ren );
			}
			//画三角边框
			//画三角形填充
			void drawTriangleFill( int x0, int y0, int x1, int y1, int x2, int y2,
						  const Color &c = Color( 255, 255, 255 ) ){
				/*int SDL_RenderDrawRect(SDL_Renderer*   renderer,
						   const SDL_Rect* rect)*/
				 SDL_Rect rect;
				 rect.x=x0;	rect.y=y0;	rect.w=x1-x0;	rect.h=y1-y0;
				SDL_SetRenderDrawColor( m_renderer, c.r, c.g, c.b, SDL_ALPHA_OPAQUE );
				SDL_RenderDrawRect( m_renderer, &rect );
			}
			//画圆
			//矩形填充
			void drawRectangleFill( int x0, int y0, int x1, int y1,
						  const Color &c = Color( 255, 255, 255 ) ){
				SDL_Rect rect;
				rect.x=x0;	rect.y=y0;	rect.w=x1-x0;	rect.h=y1-y0;
				SDL_SetRenderDrawColor( m_renderer, c.r, c.g, c.b, c.a );
				SDL_RenderFillRect( m_renderer, &rect );
			}
			//矩形边框
			void drawRectangle( int x0, int y0, int x1, int y1,
						  const Color &c = Color( 255, 255, 255 ) ){
				SDL_Rect rect;
				rect.x=x0;	rect.y=y0;	rect.w=x1-x0;	rect.h=y1-y0;
				SDL_SetRenderDrawColor( m_renderer, c.r, c.g, c.b, c.a );
				SDL_RenderDrawRect( m_renderer, &rect );
			}
			//GCurrentGraphics->SetSmoothingMode( Gdiplus::SmoothingModeHighQuality );
			void enableSmoothingMode( bool enable ){
			}
			/* 清空当前缓冲区, 并将其颜色设置为黑色 */
			void clearBuffer( const Color &c = Color() ){
				SDL_SetRenderDrawColor( m_renderer, c.r, c.g, c.b, c.a );
				SDL_RenderClear ( m_renderer );
			}
			/* 将已经绘制好的缓冲区递交给Graphics在屏幕上绘制, 并将当前缓冲区设置为另一个缓冲区 */
			void fillBuffer( ){
				SDL_RenderPresent(m_renderer);
			}
			//getWindowWidth
			int getRenderWidth();
			int getRenderHeight();
			int getWindowWidth(){
				//SDL_GetWindowSize(SDL_Window* window,   int*        w,   int*        h)
				int w, h;	//SDL_GetRendererOutputSize
				SDL_GetWindowSize( m_window, &w, &h );
				return w;
			}
			int getWindowHeight(){
				int w, h;
				SDL_GetWindowSize( m_window, &w, &h );
				return h;
			}
			static SDL_Window* createWindow(){
				SDL_Init(SDL_INIT_VIDEO);
				SDL_Window* window = SDL_CreateWindow("SDL_Window", 
						SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 240, 400, SDL_WINDOW_SHOWN ); 
				//SDL_MapRGB(WindowScreen->format, 0x00, 0xFF, 0x00);
				return window;
			}
			static void render( SDL_Window* window, SDL_Renderer *renderer ){
				/*SDL_Renderer* SDL_CreateRenderer(SDL_Window* window,
                                 int         index,
                                 Uint32      flags)*/
                 //SDL_Renderer* SDL_GetRenderer(SDL_Window* window)
				//是不是可以通过以下代码实现获得renderer，实现功能
				//SDL_Renderer *renderer = SDL_GetRenderer( window );
				SDL_SetRenderDrawColor( renderer, 255, 255, 0, SDL_ALPHA_OPAQUE );
				SDL_RenderClear ( renderer );
				SDL_SetRenderDrawColor( renderer, 0, 0, 0, SDL_ALPHA_OPAQUE );
				SDL_RenderDrawLine( renderer, 0, 0, 100, 100 );
				SDL_Rect rect;
				rect.x=15;	rect.y=15;	rect.w=200;	rect.h=200;
				SDL_SetRenderDrawColor( renderer, 10, 0, 255, SDL_ALPHA_OPAQUE );
				SDL_RenderDrawRect( renderer, &rect );
				SDL_RenderPresent( renderer );
			}
			static void eventloop( SDL_Window* window, SDL_Renderer * renderer )
			{
				SDL_Event myEvent;//事件
				int x,y;	short delta;
				//int quit = 0;
				while(1){
					//获得消息
					//int SDL_PollEvent(SDL_Event* event)
					//event		the SDL_Event structure to be filled with the next event from the queue, or NULL
					//If event is not NULL, the next event is removed from the queue and stored in the SDL_Event structure pointed to by event.
					//If event is NULL, it simply returns 1 if there is an event in the queue, but will not remove it.
					//while ( SDL_PollEvent ( &myEvent ) ) //从队列里取出事件
					while ( SDL_WaitEvent( &myEvent ) )
					{
						//获得事件
						//获得信号呢
						switch ( myEvent.type ) //根据事件类型分门别类去处理
						{
							 case SDL_QUIT: 	//何时收到这个信息
								SDL_Quit();
							case SDL_KEYUP:
								break;
							case SDL_WINDOWEVENT:
								switch (myEvent.window.event) {
									case SDL_WINDOWEVENT_SHOWN:
										SDL_Log("Window %d shown", myEvent.window.windowID);
										break;
									case SDL_WINDOWEVENT_HIDDEN:
										break;
									case SDL_WINDOWEVENT_EXPOSED:
										SDL_Log("Window %d exposed", myEvent.window.windowID);
										render( window, renderer );
										break;
									case SDL_WINDOWEVENT_CLOSE:
										SDL_Log("Window %d closed", myEvent.window.windowID);
										close( window );
										break;
								}
								break;
							default:
							//1024	SDL_MOUSEMOTION    = 0x400
							//512		SDL_WINDOWEVENT    = 0x200
								SDL_Log( "event type: %d", myEvent.type );
								break;
						}
					}
				}
			}
			static void close( SDL_Window* window ){
				SDL_DestroyWindow( window );
				SDL_QuitSubSystem(SDL_INIT_VIDEO);
				SDL_Quit();
				exit( 0 );
			}
			//demo1
			static void demo1(){
				//建立一个窗口,试试这个模块的功能
				//如何用到renderer
				SDL_Window* window = createWindow();
				SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, 0 );
				//SDL_Delay( 2000 );
				//信息的汇聚.
				eventloop( window, renderer );
			}
			//demo2
			static void demo2(){
				SDL_Window* window = createWindow();
				//SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, 0 );
				Draw draw( window );
				SDL_Event myEvent;//事件
				int x,y;	short delta;
				//int quit = 0;
				while(1){
					//获得消息
					//int SDL_PollEvent(SDL_Event* event)
					//event		the SDL_Event structure to be filled with the next event from the queue, or NULL
					//If event is not NULL, the next event is removed from the queue and stored in the SDL_Event structure pointed to by event.
					//If event is NULL, it simply returns 1 if there is an event in the queue, but will not remove it.
					//while ( SDL_PollEvent ( &myEvent ) ) //从队列里取出事件
					while ( SDL_WaitEvent( &myEvent ) )
					{
						//获得事件
						//获得信号呢
						switch ( myEvent.type ) //根据事件类型分门别类去处理
						{
							 case SDL_QUIT: 	//何时收到这个信息
								SDL_Quit();
							case SDL_KEYUP:
								break;
							case SDL_WINDOWEVENT:
								switch (myEvent.window.event) {
									case SDL_WINDOWEVENT_SHOWN:
										SDL_Log("Window %d shown", myEvent.window.windowID);
										break;
									case SDL_WINDOWEVENT_HIDDEN:
										break;
									case SDL_WINDOWEVENT_EXPOSED:
										SDL_Log("Window %d exposed", myEvent.window.windowID);
										//draw.fillTriangle( 15, 15, 50, 50 );
										draw.clearBuffer( );
										//point, line, rectange, circle, string
										draw.drawPoint( 10, 10, 255, 0, 0, 255 );
										draw.drawLine( 20, 10, 20, 70,  Color( 0, 255, 0 ) );
										draw.drawString( "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf", 28, 50, 50, "test1" );
										draw.fillBuffer();
										break;
									case SDL_WINDOWEVENT_CLOSE:
										SDL_Log("Window %d closed", myEvent.window.windowID);
										close( window );
										break;
								}
								break;
							default:
							//1024	SDL_MOUSEMOTION    = 0x400
							//512		SDL_WINDOWEVENT    = 0x200
								SDL_Log( "event type: %d", myEvent.type );
								break;
						}
					}
				}
			}
		};
	}
}
